package com.qinggeng.project.tool.pay.controller;

import cn.hutool.json.JSON;
import com.alibaba.fastjson.JSONObject;
import com.qinggeng.common.exception.CustomException;
import com.qinggeng.common.utils.DateUtils;
import com.qinggeng.common.utils.StringUtils;
import com.qinggeng.framework.aspectj.lang.annotation.Log;
import com.qinggeng.framework.aspectj.lang.enums.BusinessType;
import com.qinggeng.framework.security.annotation.AnonymousAccess;
import com.qinggeng.framework.web.domain.AjaxResult;
import com.qinggeng.project.api.security.utils.ApiUtils;
import com.qinggeng.project.system.domain.Member;
import com.qinggeng.project.system.domain.SysUser;
import com.qinggeng.project.system.dto.MemberDTO;
import com.qinggeng.project.system.service.ISysUserService;
import com.qinggeng.project.system.service.MemberService;
import com.qinggeng.project.tool.pay.domain.vo.TradeVo;
import com.qinggeng.project.tool.pay.service.AliPayService;
import com.qinggeng.project.tool.pay.service.WxPayService;
import com.qinggeng.project.tool.pay.utils.PayUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.math.BigDecimal;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZoneOffset;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 支付配置
 *
 * @author wangkh
 * @date 2020-02-13
 */
@Slf4j
@RestController
@RequestMapping("${toolPath}/pay")
public class PayController {

    @Autowired
    private AliPayService aliPayService;

    @Autowired
    private WxPayService wxPayService;

    @Autowired
    private RedisTemplate redisTemplate;


    @Autowired
    private MemberService memberService;

    @Autowired
    private  ISysUserService sysUserService;

    /**
     * 支付宝支付测试
     * @param type 支付类型
     * @param price 支付金额
     * @return /
     */
    @PreAuthorize("@ss.hasPermi('tool:pay:index')")
    @Log(title = "支付宝支付测试", businessType = BusinessType.OTHER)
    @PostMapping(value = "/toTestAsAliPay/{type}/{price}")
    public AjaxResult  toTestAsAliPay(@PathVariable(name = "type") String type,@PathVariable(name = "price") BigDecimal price) {
        AjaxResult ajaxResult = AjaxResult.success();
        try {
            TradeVo tradeVo = new TradeVo();
            tradeVo.setOutTradeNo(PayUtils.getOrderCode());
            tradeVo.setTotalAmount(price);
            tradeVo.setSubject("支付宝支付测试-"+PayUtils.getOrderCode());
            String result = null;
            switch (type){
                case "web":
                case "wap":
                    result = aliPayService.toPayAsWeb(tradeVo);
                    ajaxResult.put("payUrl",result);
                    ajaxResult.put("way",1);
                    break;
                case "app":
                    ajaxResult.put("data",aliPayService.toPayAsApp(tradeVo));
                    ajaxResult.put("way",2);
                    break;
                case "scan":
                    ajaxResult.put("data",aliPayService.toPayAsScan(tradeVo));
                    ajaxResult.put("way",3);
                    break;
                default:
                    throw new CustomException("支付测试异常请检查控制台");
            }
       }catch (Exception e){
            System.out.println(e.getMessage());
           throw new CustomException("支付测试异常请检查控制台");
       }
        return ajaxResult;
    }


    /**
     * 微信支付测试
     * @param type 支付类型
     * @param price 支付金额
     * @return /
     */
    @PreAuthorize("@ss.hasPermi('tool:pay:index')")
    @Log(title = "微信支付测试", businessType = BusinessType.OTHER)
    @PostMapping(value = "/toTestAsWxPay/{type}/{price}")
    public AjaxResult  toTestAsWxPay(@PathVariable(name = "type") String type,@PathVariable(name = "price") BigDecimal price) {
        AjaxResult ajaxResult = AjaxResult.success();
        try {
            TradeVo tradeVo = new TradeVo();
            tradeVo.setOutTradeNo(PayUtils.getOrderCode());
            tradeVo.setTotalAmount(price);
            tradeVo.setSubject("微信支付测试-"+PayUtils.getOrderCode());
            String result = null;
            switch (type){
                case "web":
                    ajaxResult.put("data",wxPayService.toPayAsWeb(tradeVo));
                    ajaxResult.put("way",3);
                    break;
                case "wap":
                    result = wxPayService.toPayAsWap(tradeVo);
                    ajaxResult.put("payUrl",result);
                    ajaxResult.put("way",1);
                    break;
                case "app":
                    ajaxResult.put("data",wxPayService.toPayAsApp(tradeVo));
                    ajaxResult.put("way",2);
                    break;
                case "scan":
                    ajaxResult.put("data",wxPayService.toPayAsScan(tradeVo));
                    ajaxResult.put("way",3);
                    break;
                case "mp":
                    ajaxResult.put("data",wxPayService.toPayAsMp(tradeVo));
                    ajaxResult.put("way",3);
                    break;
                case "miniapp":
                    ajaxResult.put("data",wxPayService.toPayAsMiniapp(tradeVo));
                    ajaxResult.put("way",3);
                    break;
                default:
                    throw new CustomException("支付测试异常请检查控制台");
            }
        }catch (Exception e){
            System.out.println(e.getMessage());
            throw new CustomException("支付测试异常请检查控制台");
        }
        return ajaxResult;
    }


    /**
     * 支付异步通知(要公网访问)
     * @param request HttpServletRequest
     * @return /
     */
    @RequestMapping("/notify/alipay")
    @AnonymousAccess
    public String notifyAlipay(HttpServletRequest request){
        System.out.println("进入回调");
        Map<String, String[]> parameterMap = request.getParameterMap();
        if (aliPayService.rsaCheck(request)){
            if (aliPayService.notifyCallback(parameterMap)){
                return "success";
            }else{
                return "failure";
            }
        }else{
            return "failure";
        }
    }

    /**
     * 支付宝 免密周期支付
     * @param request HttpServletRequest
     * @return /
     */
    @RequestMapping("/notify/cycleUrl")
    @AnonymousAccess
    public String cycleUrl(HttpServletRequest request){
        log.info("进入会员购买回调");
        Map<String, String[]> parameterMap = request.getParameterMap();
        boolean bl=aliPayService.rsaCheck(request);
        log.info("回调回调验证 {} ",bl);
        if (bl){
            String vipParam=parameterMap.get("out_trade_no")[0];
            log.info("回调订单号 {} ",vipParam);

            if (StringUtils.isEmpty(vipParam)){
                return "failure";
            }
            String[] params=vipParam.split("-");
            if (params.length!=3){
                return "failure";
            }
            String type=  params[1];
            Long userId=  Long.valueOf(params[2]);
            SysUser sysUser=sysUserService.selectUserById(userId);
            if (userId==null){
                return "failure";
            }
            MemberDTO dto =new MemberDTO();
            dto.setUserId(userId);
            dto.setPhonenumber(sysUser.getPhonenumber());
            LocalDate localDate = LocalDate.now();
            LocalDate endDate=localDate.plusDays(7);
            Date date = Date.from(endDate.atStartOfDay(ZoneOffset.ofHours(8)).toInstant());
            dto.setEndTime(date);
            dto.setVipType(Integer.valueOf(type));
            memberService.insertMember(dto);
            return "success";
        }else{
            return "failure";
        }
    }

    /**
     * 支付异步通知(要公网访问)
     * @param request HttpServletRequest
     * @return /
     */
    @RequestMapping("/notify/wechat")
    @AnonymousAccess
    public String notifyWechat(HttpServletRequest request){
        Map<String, String> parameterMap = PayUtils.parseRequest(request);
        try {
            if (wxPayService.rsaCheck(parameterMap)){
                if (wxPayService.notifyCallback(parameterMap)){
                    return "success";
                }else{
                    return "failure";
                }
            }else{
                return "failure";
            }
        }catch (Exception e){
            throw new CustomException("回调异常");
        }
    }

}
